"""
Copyright (C) 2009 Attila-Mihaly Balazs

TwitFeeder is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

TwitFeeder is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU Affero General Public License
along with TwitFeeder.  If not, see <http://www.gnu.org/licenses/>
"""
import unittest
import workhorse
from workhorse import StatusFetcher
from os import environ

FETCHFILES = {
    'http://twitter.com/help/test.json' : 'testdata/twitter_test.json',
    'http://twitter.com/statuses/user_timeline/bagder.json' : 'testdata/twitter_user_bagder.json',

    'http://daniel.haxx.se/blog/2009/12/26/my-open-source-tv/' : None,
    'http://tools.ietf.org/html/draft-oiwa-http-mutualauth-05' : None,
    'http://daniel.haxx.se/blog/2009/12/21/going-fosdem-2010/' : None,
    'http://curl.haxx.se/mail/lib-2009-12/0071.html' : None,
    'http://foss-sthlm.haxx.se/.' : None,
    'http://daniel.haxx.se/blog/2009/12/11/foss-sthlm/' : None,

    'http://identi.ca/api/help/test.json' : 'testdata/identica_test.json',
    'http://identi.ca/api/statuses/user_timeline/evan.json' : 'testdata/identica_user_evan.json',

    'http://twitter-api.wordpress.com/statuses/user_timeline/decipherinfosys.json' : 'testdata/wordpress_user_decipherinfosys.json',

    'http://search.twitter.com/search.json?q=%23zacon' : 'testdata/twitter_hash_zacon.json',

    'http://search.twitter.com/search.json?q=%23twitter' : 'testdata/twitter_hash_twitter.json',

    'http://identi.ca/api/search.json?q=%23identica' : 'testdata/identica_hash_identica.json',

    'http://identi.ca/api/search.json?q=%23twitter' : 'testdata/identica_hash_twitter.json',

    'http://twitter.com/CB4Free' : None,
    'http://eCa.sh/LxES' : None,

    'http://twitter.com/statuses/user_timeline/tollerton.json' : 'testdata/twitter_user_tollerton.json',

    'http://uksnow.benmarsh.co.uk' : None,
    'http://fontgameapp.com' : None,
}

class MockResult:
    content = None
    status_code = 404
    headers = {}

    def __init__(self, status=200, fileName=None):
        if fileName:
            f = open(fileName, 'r')
            self.content = f.read()
            f.close()
        self.status_code = status

def mock_do_fetch(url, headers=None, data=None, timeout=None,
    memcacheKey=None, memcacheTimeout=None):
    if 0 == url.find('http://bit.ly/') \
        or 0 == url.find('http://wp.me/') \
        or 0 == url.find('http://twitpic.com/') \
        or 0 == url.find('http://is.gd/') \
        or 0 == url.find('http://4sq.com/') \
        or 0 == url.find('http://j.mp/') \
        or 0 == url.find('http://tinyurl.com/'):
        return MockResult(404)
        
    if url in FETCHFILES:
        return MockResult(200, FETCHFILES[url])
    else:
        print "No testfile for %s" % url
        return MockResult(404)

class MockMemcache:
    def add(self, key, data, timeout=None):
        pass

    def get(self, key):
        return None

workhorse.DOFETCH = mock_do_fetch
workhorse.MEMCACHE = MockMemcache()

environ['SERVER_NAME']     = 'localhost'
environ['SERVER_PORT']     = '80'
environ['wsgi.url_scheme'] = 'http'

class TestsTestCase(unittest.TestCase):
    def test_spiceup_text(self):
        text = "Foo bar @foobar http://helloworld.com #barfoo :-)"
        self.assertEqual('Foo bar &#8203;@<a href=\'{{ base_url }}/foobar\'>foobar</a> <a href=\'http://helloworld.com\'>http://helloworld.com</a> &#8203;#<a href=\'{{ base_url }}/search?q=barfoo\'>barfoo</a> <img width="15" height="15" src="{{ root_url }}/static/smileys/icon_smile.gif" alt=":-)">',
            StatusFetcher._spiceup_text(text, 'twitter.com', False))
        text = "foo@bar"
        self.assertEqual('<a href="mailto:foo@bar">foo@bar</a>', StatusFetcher._spiceup_text(text, 'twitter.com', False))

    def test_urlparser(self):
        for url in ["http://www.Twitter.com/foobar", "twitter.com/@foobar",
            "foobar", "@foobar"]:
            (baseUrl, user) = StatusFetcher.extract_url_parts(url)
            self.assertEqual('twitter.com', baseUrl, url)
            self.assertEqual('foobar', user, url)

        (baseUrl, user) = StatusFetcher.extract_url_parts("twitter.com/#foobar")
        self.assertEqual('twitter.com', baseUrl, "twitter.com/#foobar")
        self.assertEqual('#foobar', user, "twitter.com/#foobar")

        (baseUrl, user) = StatusFetcher.extract_url_parts("#foobar")
        self.assertEqual('twitter.com', baseUrl, "#foobar")
        self.assertEqual('#foobar', user, "#foobar")

        for url in ["http://army.twit.tv/foobar", "army.twit.tv/@foobar",
            "Https://army.twit.tv/foobar"]:
            (baseUrl, user) = StatusFetcher.extract_url_parts(url)
            self.assertEqual('army.twit.tv', baseUrl, url)
            self.assertEqual('foobar', user, url)

        (baseUrl, user) = StatusFetcher.extract_url_parts("army.twit.tv/asdf/#foobar")
        self.assertEqual('army.twit.tv/asdf', baseUrl, "army.twit.tv/asdf/#foobar")
        self.assertEqual('#foobar', user, "army.twit.tv/asdf/#foobar")

    def test_get_api(self):
        api = StatusFetcher._get_api('twitter.com', doTest=False)
        self.assertEqual('http://twitter.com', api._base_url)
        api = StatusFetcher._get_api('identi.ca', doTest=False)
        self.assertEqual('http://identi.ca/api', api._base_url)
        api = StatusFetcher._get_api('decipherinfosys.wordpress.com', doTest=False)
        self.assertEqual('http://twitter-api.wordpress.com', api._base_url)

class IntegrationTests(unittest.TestCase):
    def test_twitter_bagder(self):
        feed = StatusFetcher.fetch_feed('bagder', 'twitter.com')
        self.assertFalse(feed['is_hashtagfeed'])
        self.assertEqual(20, len(feed['statuses']))
        status = feed['statuses'][0]
        self.assertEqual('newly blogged: "my open source TV" <a href=\'http://daniel.haxx.se/blog/2009/12/26/my-open-source-tv/\'>http://daniel.haxx.se/&#8203;blog/&#8203;2009/&#8203;12/&#8203;26/&#8203;my-open-source-tv/</a>', status.text)
        self.assertEqual('newly blogged: "my open source TV" http://daniel.haxx.se/blog/2009/12/26/my-open-source-tv/', status.title)
        self.assertEqual('2009-12-26 23:08:22', str(status.created_at_date))
        self.assertEqual('http://twitter.com/bagder/status/7072888508', status.link)
        self.assertEqual(None, status.geo)
        self.assertEqual(None, status.geolink)

    def test_identica_evan(self):
        feed = StatusFetcher.fetch_feed('evan', 'identi.ca')
        self.assertFalse(feed['is_hashtagfeed'])
        self.assertEqual(20, len(feed['statuses']))
        status = feed['statuses'][0]
        self.assertEqual("&#8203;@<a href='http://identi.ca/rkj'>rkj</a> do you call 611 for directory assistance? If not, why insist on sending spam reports anywhere but &#8203;@<a href='http://identi.ca/support,'>support,</a> where we read them?", status.text)
        self.assertEqual('@rkj do you call 611 for directory assistance? If not, why insist on sending spam reports anywhere but @support, where we read them?', status.title)
        self.assertEqual('2009-12-27 02:15:19', str(status.created_at_date))
        self.assertEqual('http://identi.ca/notice/17552874', status.link)
        self.assertEqual('Point', status.geo['type'])

    def test_wordpress_decipherinfosys(self):
        feed = StatusFetcher.fetch_feed('decipherinfosys', 'wordpress.com')
        self.assertFalse(feed['is_hashtagfeed'])
        self.assertEqual(25, len(feed['statuses']))
        status = feed['statuses'][0]
        self.assertEqual("Getting Started with the Azure Platform: We have talked about MSFT Azure in some of our posts in the past but start... <a href='http://wp.me/p2TPI-DR'>http://wp.me/&#8203;p2TPI-DR</a>", status.text)
        self.assertEqual('Getting Started with the Azure Platform: We have talked about MSFT Azure in some of our posts in the past but start... http://wp.me/p2TPI-DR', status.title)
        self.assertEqual('2009-12-24 14:21:19', str(status.created_at_date))
        self.assertEqual('http://wp.me/p2TPI-DR', status.link)
        self.assertEqual(None, status.geo)

    def test_twitter_hash_zacon(self):
        feed = StatusFetcher.fetch_feed('#zacon', 'twitter.com')
        self.assertTrue(feed['is_hashtagfeed'])
        self.assertEqual(0, len(feed['statuses']))

    def test_twitter_hash_twitter(self):
        feed = StatusFetcher.fetch_feed('#twitter', 'twitter.com')
        self.assertTrue(feed['is_hashtagfeed'])
        self.assertEqual(15, len(feed['statuses']))
        status = feed['statuses'][0]
        self.assertEqual("[hey] 2 my &#8203;#<a href='http://twitter.com/search?q=myspace'>myspace</a> &#8203;#<a href='http://twitter.com/search?q=in'>in</a> &#8203;#<a href='http://twitter.com/search?q=facebook'>facebook</a> &amp; &#8203;#<a href='http://twitter.com/search?q=twitter'>twitter</a> families pls feel free 2check out www.twitter.com/hcp520 &amp; hav a look at my favs &amp; feed. :O]", status.text)
        self.assertEqual('[hey] 2 my #myspace #in #facebook &amp; #twitter families pls feel free 2check out www.twitter.com/hcp520 &amp; hav a look at my favs &amp; feed. :O]', status.title)
        self.assertEqual('2009-12-27 12:19:51', str(status.created_at_date))
        self.assertEqual('http://twitter.com/hcp520/status/7088887884', status.link)
        self.assertEqual(None, status.geo)

    def test_identica_hash_identica(self):
        feed = StatusFetcher.fetch_feed('#identica', 'identi.ca')
        self.assertTrue(feed['is_hashtagfeed'])
        self.assertEqual(1, len(feed['statuses']))
        status = feed['statuses'][0]
        self.assertEqual(u'RT &#8203;@<a href=\'http://identi.ca/meinhard\'>meinhard</a> &#8203;@<a href=\'http://identi.ca/meinhard\'>meinhard</a> deleted more &#8203;#<a href=\'http://identi.ca/tag/identica\'>identica</a> &#8203;#<a href=\'http://identi.ca/tag/spam\'>spam</a> users from !ecobytes - &#8203;#<a href=\'http://identi.ca/tag/StatusNet\'>StatusNet</a> needs a "report user" button - please REDENT', status.text)
        self.assertEqual('RT @meinhard @meinhard deleted more #identica #spam users from !ecobytes - #StatusNet needs a "report user" button - please REDENT', status.title)
        self.assertEqual('2009-12-27 12:06:30', str(status.created_at_date))
        self.assertEqual('http://identi.ca/notice/17575433', status.link)
        self.assertEqual(None, status.geo)

    def test_identica_hash_twitter(self):
        feed = StatusFetcher.fetch_feed('#twitter', 'identi.ca')
        self.assertTrue(feed['is_hashtagfeed'])
        self.assertEqual(6, len(feed['statuses']))
        status = feed['statuses'][0]
        self.assertEqual(u"Ich hab die Kommentare nicht gesammelt und w\xfcrde sie auch nicht wiedergeben, aber gesehen habe ich sie bei Twitter mit Hashtag &#8203;#<a href='http://identi.ca/tag/26c3'>26c3</a>", status.text)
        self.assertEqual(u'Ich hab die Kommentare nicht gesammelt und w\xfcrde sie auch nicht wiedergeben, aber gesehen habe ich sie bei Twitter mit Hashtag #26c3', status.title)
        self.assertEqual('2009-12-27 12:15:53', str(status.created_at_date))
        self.assertEqual('http://identi.ca/notice/17575844', status.link)
        self.assertEqual(None, status.geo)

    def test_twitter_geolocation(self):
        feed = StatusFetcher.fetch_feed('tollerton', 'twitter.com')
        self.assertFalse(feed['is_hashtagfeed'])
        self.assertEqual(19, len(feed['statuses']))
        status = feed['statuses'][0]
        self.assertEqual("I do love a dark Erdinger. <a href='http://twitpic.com/v78w0'>http://twitpic.com/&#8203;v78w0</a>", status.text)
        self.assertEqual('I do love a dark Erdinger. http://twitpic.com/v78w0', status.title)
        self.assertEqual('2009-12-25 20:33:36', str(status.created_at_date))
        self.assertEqual('http://twitter.com/tollerton/status/7041332421', status.link)
        self.assertEqual('Point', status.geo['type'])
        self.assertEqual('http://www.openstreetmap.org/?mlat=51.4471&mlon=0.1284&zoom=15', status.geolink)

if __name__ == '__main__':
    unittest.main()
